class_name 泊松盘采样器类

var 画布尺寸:Vector2i
var 起始坐标:Vector2
var 终点坐标:Vector2

func 坐标点符合条件(网格数据:Array, 网格边长:float, 最大网格序号X:int,  最大网格序号Y:int, 随机坐标点:Vector2,  半径:float)->bool: 
		if 随机坐标点.x < 0 or 随机坐标点.x >= 画布尺寸.x or 随机坐标点.y < 0 or 随机坐标点.y>= 画布尺寸.y:
			return false;

		var 网格序号X:int = floor(随机坐标点.x / 网格边长)
		var 网格序号Y:int = floor(随机坐标点.y / 网格边长)
		var 起始网格序号X:int = max(网格序号X - 1, 0)
		var 终止网格序号X:int = max(网格序号X + 1, 最大网格序号X - 1)
		var 起始网格序号Y:int = max(网格序号Y - 1, 0)
		var 终止网格序号Y:int = max(网格序号Y + 1, 最大网格序号Y - 1);

		for i in range(起始网格序号X,终止网格序号X+1):
			for j in range(起始网格序号Y,终止网格序号Y+1):
				if 网格数据[i][j] != null:
					if 网格数据[i][j].distance_to(随机坐标点) < 半径:
						return false;

		return true;

func 插入坐标点(网格数据:Array[Array], 网格边长:float, 坐标点:Vector2): 
	var 网格序号X:int = floor(坐标点.x/ 网格边长)
	var 网格序号Y:int = floor(坐标点.y/ 网格边长)
	网格数据[网格序号X][网格序号Y] = 坐标点;

func 采样(_画布尺寸:Vector2i,半径:float, 尝试次数:int, 圆形:bool=true)->Array[Vector2]:
	画布尺寸=_画布尺寸
	const N:int = 2;
	var 坐标点数据:Array[Vector2] =[]
	var 当前待生成坐标集:Array[Vector2] =[]
	
	var 网格数据:Array[Array]=[];
	var 网格边长:float = floor(半径/sqrt(N))

	var 最大网格序号X:int = ceil(画布尺寸.x/网格边长)+ 1
	var 最大网格序号Y:int = ceil(画布尺寸.y/网格边长)+ 1

	for i in range(最大网格序号X):
		var 数组:Array=[]
		数组.resize(最大网格序号Y)
		数组.fill(null)
		网格数据.append(数组)
		
	起始坐标=Vector2(画布尺寸.x*0.5,画布尺寸.y*0.95)
	终点坐标=Vector2(画布尺寸.x*0.5,画布尺寸.y*0.05)	
	
	插入坐标点(网格数据, 网格边长, 起始坐标)
	坐标点数据.append(起始坐标)
	当前待生成坐标集.append(起始坐标)
	
	插入坐标点(网格数据, 网格边长, 终点坐标)
	坐标点数据.append(终点坐标)
	当前待生成坐标集.append(终点坐标)

	while 当前待生成坐标集.size()>0:
		var 随机序号:int = randi_range(0,当前待生成坐标集.size()-1)
		var 当前坐标点:Vector2 = 当前待生成坐标集[随机序号]
		
		var 找到坐标点:bool = false
		for i in range(尝试次数):
			var 随机角度:float = randf_range(0,360)
			var 随机半径:float = randf_range(半径, 2*半径)
			var 随机X:float = 当前坐标点.x + 随机半径 * cos(deg_to_rad(随机角度))
			var 随机Y:float= 当前坐标点.y + 随机半径 * sin(deg_to_rad(随机角度))
			var 随机坐标点:Vector2 = Vector2(随机X, 随机Y)
			
			if !坐标点符合条件(网格数据, 网格边长,最大网格序号X, 最大网格序号Y,随机坐标点, 半径):
				continue;
			
			坐标点数据.append(随机坐标点);
			插入坐标点(网格数据, 网格边长, 随机坐标点);
			当前待生成坐标集.append(随机坐标点);
			找到坐标点 = true;
			break;
		
		if !找到坐标点:
			当前待生成坐标集.remove_at(随机序号);
		
	if 圆形:	
		var 圆形坐标集:Array[Vector2]=[]
		for 坐标 in 坐标点数据:
			var 距离=Vector2(坐标).distance_to(Vector2(画布尺寸.x*0.5,画布尺寸.y*0.5))
			if 距离<=画布尺寸.y*0.45:
				圆形坐标集.append(坐标)
		坐标点数据=圆形坐标集

	return 坐标点数据
